package com.archgeek.java.conc.future;

import org.apache.commons.lang3.RandomUtils;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.*;

/**
 * @author pizhihui
 * @date 2020-11-04
 */
public class CompletableFutureDemo {

    @Test
    public void test1() {

//
//        try {
//            Double cf = CompletableFuture.supplyAsync(CompletableFutureDemo::fetchPrice)
//                    .get(50, TimeUnit.MILLISECONDS);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } catch (ExecutionException e) {
//            e.printStackTrace();
//        } catch (TimeoutException e) {
//            System.out.println("超时错误");
//            e.printStackTrace();
//        }
//                .whenComplete((res, e) -> {
//                    if (e != null) {
//                        System.out.println("异常" );
//                        return;
//                    }
//                    System.out.println("结果" + res);
//                });
//        cf.thenAccept(res -> {
//            System.out.println("成功");
//        });
//        cf.exceptionally(e -> {
//            System.out.println("异常");
//
//            e.printStackTrace();
//            return null;
//        });

        long start = System.currentTimeMillis();
        CompletableFuture.supplyAsync(CompletableFutureDemo::fetchPrice)
                .whenComplete((res, e) -> {
                    if (e != null) {
                        System.out.println("异常");
                        e.printStackTrace();
                        return;
                    }
                    System.out.println("结果" + res);
                });


        System.out.println("end............" + (System.currentTimeMillis() - start));
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void doSomething() {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException( "step1", e);
        }
        int i = 1/0;
    }

    @Test
    public void test5() {

        CompletableFuture<String> maturityFuture =CompletableFuture.supplyAsync(() -> {
            System.out.println("第一步开始");
            doSomething();
            return "step1";
        }).thenApply((r) -> {
            System.out.println("第二步开始");
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "step2";
        }).handle((res, ex) -> {
            System.out.println(res + ",,,ex,,," + ex);
            return "xxx";
        });
        try {
            maturityFuture.get();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("结束任务");
    }


    static Double fetchPrice() {
        try {
            Thread.sleep(100* (long) Math.random());
        } catch (InterruptedException e) {
        }
//        if (Math.random() < 0.3) {
//            throw new RuntimeException("fetch price failed!");
//        }
        return 5 + Math.random() * 20;
    }


    @Test
    public void test2() {

        Executor executor = Executors.newScheduledThreadPool(2);

        CompletableFuture<Double> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("create bulk demo....");
            try {
                TimeUnit.SECONDS.sleep(RandomUtils.nextInt(10, 20));
                return 5 + Math.random() * 20;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, executor);

        future.thenApplyAsync(num -> {
            System.out.println("......");
            return new Student(num);
        }, executor);


    }

    class Student {
        Long id;
        public Student(Double d) {
            this.id = d.longValue();
        }
    }

}
